package gim_broker

import (
	"errors"
	"fmt"
	"google.golang.org/protobuf/proto"
)

const (
	AloneChat int32 = iota
	GroupChat
)

func Transfer(data []byte) error {

	msg := &TransferMsg{}
	err := proto.Unmarshal(data, msg)
	if err != nil {
		return err
	}
	if err := verifyTransferMsg(msg); err != nil {
		return err
	}

	switch msg.MsgType {
	case AloneChat:
		return aloneChat(msg)
	case GroupChat:
		return groupChat(msg)
	default:
		Logger.Errorf("不匹配的消息类型 [%d]", msg.MsgType)
		return nil
	}

}

// 校验消息属性是否准确
func verifyTransferMsg(msg *TransferMsg) error {

	if msg.FromId == "" {
		return errors.New("消息来源Id is nil")
	}
	if msg.MsgType == AloneChat && msg.ToId == "" {
		return errors.New("消息目标Id is nil")
	}
	if msg.MsgType == GroupChat && msg.GroupId == "" {
		return errors.New("群组消息 但是 groupId is nil")
	}
	if msg.Content == "" {
		return errors.New("消息内容 is nil")
	}
	return nil
}

// 私聊
func aloneChat(msg *TransferMsg) error {
	client := GetClientById(msg.ToId)
	if client == nil {
		return errors.New("消息目标客户端 is nil")
	}

	//transferMsg := &ClientReceiveTransferMsg{FromId: msg.FromId, Content: msg.Content}
	data, err := proto.Marshal(msg)
	if err != nil {
		return err
	}
	_, err = client.Conn.Write(encode(CommandTransfer, data))
	if err != nil {
		return err
	}
	return nil
}

// 群聊
func groupChat(msg *TransferMsg) error {

	groupId := msg.GroupId
	group := GetGroup(groupId)
	if group == nil {
		return errors.New(fmt.Sprintf("group is nil groupId [%s]", groupId))
	}

	group.m.RLock()
	for _, clientId := range group.Members {
		client := GetClientById(clientId)
		if client == nil {
			break
		}
		if client.Conn == nil {
			break
		}
		transferMsg := &TransferMsg{FromId: msg.FromId, Content: msg.Content, MsgType: GroupChat, GroupId: groupId}
		data, err := proto.Marshal(transferMsg)
		if err != nil {
			return err
		}
		_, err = client.Conn.Write(encode(CommandTransfer, data))
		if err != nil {
			return err
		}
	}
	group.m.RUnlock()
	return nil
}

// 加入群聊
func joinGroup(data []byte) {

	msg := &JoinGroupMsg{}
	err := proto.Unmarshal(data, msg)
	if err != nil {
		Logger.Error("加群失败 数据序列化失败")
		return
	}
	if msg.ClientId == "" {
		Logger.Error("加群失败 ClientId is nil")
		return
	}
	if msg.GroupId == "" {
		Logger.Error("加群失败 GroupId is nil")
		return
	}
	err = AddGroupMember(msg.GroupId, msg.ClientId)
	if err != nil {
		Logger.Error("加群失败 AddGroupMember err")
		return
	}
	Logger.Infof("加群成功 GroupId [%s] ClientId [%s]", msg.GroupId, msg.ClientId)
}
